﻿// 
//  MVVM-WPF-WinRt Markup Binding Extensions
//  Copyright © 2013-2014 Alexander Paskhin /paskhin@hotmail.co.uk/ All rights reserved.
// 
//
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using MvvmBindingPack;

namespace WpfDemoApplication.ViewModel
{
    public class MainWindowVm : MvvmViewModelBase
    {

        /// <summary>
        /// Marker locate property
        /// </summary>
        public int MarkerMain { get; set; }

        /// <summary>
        /// Constructor
        /// </summary>
        public MainWindowVm()
        {

            _commandProxyEmpty = new CommandHandlerProxy(a => { }, a => false);
            _commandProxyInstance = new CommandHandlerProxy(ExecuteMethod, CanExecuteMethod);
            _commandProxy = _commandProxyInstance;
            ButtonExecuteProperty = ExecuteMethod;
            CanExecuteProperty = CanExecuteMethod;
            ButtonClickPropDelegate = ButtonClickProp;
        }

        public override void Loaded(object sender, RoutedEventArgs e)
        {
            // Perform actions when model is loaded

            // Locate the Window for setup the Close event (u may use a XAML trick, but ?!? )
            var de = sender as DependencyObject;
            var current = BindHelper.LocateFirstParentTypeOfControlByVisualTree(de, typeof(Window)) as Window;
            if (current != null)
            {
                current.Closed += View_Closed;
            }
        }

        public void View_Closed(object sender, EventArgs e)
        {
            // Perform when model is closed
        }


        public override void Unloaded(object sender, RoutedEventArgs e)
        {
            // Perform actions when model is unloaded
        }

        /// <summary>
        /// Demo/test methods/ event handlers invocation counter.
        /// </summary>
        int _callCount;
        public int CallCounter
        {
            get { return _callCount++; }
        }

        // Legacy proper handling of Button Command property enable/ disable features.
        readonly CommandHandlerProxy _commandProxyInstance;
        readonly CommandHandlerProxy _commandProxyEmpty;
        CommandHandlerProxy _commandProxy;
        public CommandHandlerProxy CommandProxy
        {
            get
            { return _commandProxy; }
            set
            { _commandProxy = value; NotifyPropertyChanged("CommandProxy"); }
        }

        /// <summary>
        /// The "can execute" Boolean flag.
        /// </summary>
        bool _canExecuteFlag = true;
        public bool CanExecuteFlag
        {
            get { return _canExecuteFlag; }
            set
            {
                _canExecuteFlag = value;
                NotifyPropertyChanged("CanExecuteFlag");

                // Legacy proper handling of Button Command property enable/ disable features.
                CommandProxy = value ? _commandProxyInstance : _commandProxyEmpty;

                if (ActionNotifyCanExecuteChanged != null) { ActionNotifyCanExecuteChanged(); }
                if (EventHandlerNotifyCanExecuteChanged != null) { EventHandlerNotifyCanExecuteChanged(this, EventArgs.Empty); }
                if (_propertyDelegateNotifyCanExecuteChanged != null) { _propertyDelegateNotifyCanExecuteChanged(); }
            }
        }

        /// <summary>
        /// Label message for Button Click Method
        /// </summary>
        String _buttonClickMethodMsg;
        public String ButtonClickMethodMsg
        {
            get { return _buttonClickMethodMsg; }
            set { _buttonClickMethodMsg = value; NotifyPropertyChanged("ButtonClickMethodMsg"); }
        }

        /// <summary>
        /// Label message for Button Click PropDel 
        /// </summary>
        String _buttonClickPropMsg;
        public String ButtonClickPropMsg
        {
            get { return _buttonClickPropMsg; }
            set { _buttonClickPropMsg = value; NotifyPropertyChanged("ButtonClickPropMsg"); }
        }

        /// <summary>
        /// Event Handler for Button Click
        /// </summary>
        public void ButtonClickMethod(object sender, RoutedEventArgs e)
        {
            ButtonClickMethodMsg = "ButtonClickMethod Called - Counter # " + CallCounter;
        }

        /// <summary>
        /// Event Handler via delegate type property for Button Click
        /// </summary>
        private RoutedEventHandler _buttonClickPropDelegate;
        public RoutedEventHandler ButtonClickPropDelegate
        {
            get { return _buttonClickPropDelegate; }
            set { _buttonClickPropDelegate = value; NotifyPropertyChanged("ButtonClickPropDelegate"); }
        }
        private void ButtonClickProp(object sender, RoutedEventArgs e)
        {
            ButtonClickPropMsg = "ButtonClickProp Called     - Counter # " + CallCounter;
        }

        /// <summary>
        /// Label message for command Button's group: "Button Cmd-Ex ", "Button Cmd-ExCe", "Button Cmd-ExCeCh"
        /// </summary>
        String _buttonCommandMsgVariantOne;
        public String ButtonCommandMsgVariantOne
        {
            get { return _buttonCommandMsgVariantOne; }
            set { _buttonCommandMsgVariantOne = value; NotifyPropertyChanged("ButtonCommandMsgVariantOne"); }
        }


        public Action<object> ButtonExecuteProperty { get; set; }
        public void ExecuteMethod(object sender)
        {
            ButtonCommandMsgVariantOne = "ExecuteMethod Called - Counter # " + CallCounter;
        }

        public Func<object, bool> CanExecuteProperty { get; set; }
        public bool CanExecuteMethod(object sender)
        {
            return CanExecuteFlag;
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")]
        public event Action ActionNotifyCanExecuteChanged;
        public event EventHandler EventHandlerNotifyCanExecuteChanged;


        private Action _propertyDelegateNotifyCanExecuteChanged;
        public Action PropertyDelegateNotifyCanExecuteChanged
        {
            get { return _propertyDelegateNotifyCanExecuteChanged; }
            set { _propertyDelegateNotifyCanExecuteChanged = value; }
        }

    }
}
